const RENDER_TO_DOM = Symbol("render to dom")
// 包装对象 ElementWrapper
// 包装对象 TextWrapper
/**
 * 给原生DOCUMENT对象添加两个方法 并使root代理它 从而适配上自定义组件的生成方式
 */
class ElementWrapper {

    constructor(type) {
        this.root = document.createElement(type)
    }
    setAttribute(name, value){
        // ([\s\S]) 表示所有的字符
        if(name.match(/^on([\s\S]+)$/)){
            // RegExp.$1.replace(/^[\s\S]/, c => c.toLocaleLowerCase() 将点击事件全小写
            this.root.addEventListener(RegExp.$1.replace(/^[\s\S]/, c => c.toLocaleLowerCase()), value);
        } else {
            this.root.setAttribute(name, value)
        }
    }
    appendChild(component) {
        let range = document.createRange();
        range.setStart(this.root, this.root.childNodes.length);
        range.setEnd(this.root, this.root.childNodes.length);
        range.deleteContents();
        component[RENDER_TO_DOM](range);
        // this.root.appendChild(component.root);
    }
    [RENDER_TO_DOM](range) {
        // range操作渲染
        range.deleteContents()
        range.insertNode(this.root)
    }
}
class TextWrapper {
    constructor(content) {
        // 创建文本节点
        this.root = document.createTextNode(content)
    }
    [RENDER_TO_DOM](range) {
        // range操作渲染
        range.deleteContents()
        range.insertNode(this.root)
    }
    // 文本节点没有属性 没有子节点
}

export class Component {
    constructor(content) {
        this.props = Object.create(null);
        this.children = [];
        this._root = null;
        this._range = null;

    }
    setAttribute(name, value){
        this.props[name] = value;
    }
    appendChild(component) {
        this.children.push(component);
    }
    [RENDER_TO_DOM](range) {
        // range操作渲染
        this._range = range;
        this.render()[RENDER_TO_DOM](range)
    }
    /**
     * 重新渲染
     */
    reRender() {
        this._range.deleteContents();
        this[RENDER_TO_DOM](this._range);
    }
    setState(newState) {
        // this.state判空 !typeof 也是个object
        if(this.state === null || typeof this.state !== 'object'){
            this.state = newState;
            this.reRender();
            return
        }
        // oldState newState 都是object
        let merge = function(oldState, newState) {
            // 把newState所有属性抄写到oldState上
            for (const p in newState) {
                if (oldState[p] === null || typeof oldState[p] !== 'object') {
                    newState[p] = oldState[p];

                } else {
                    merge(oldState[p], newState[p])
                }
            }
        }
        merge(this.state, newState);
        this.reRender();
    }
    // /**
    //  * 跟渲染相关
    //  */
    // get root() {
    //     if(!this._root){
    //         this._root = this.render().root;
    //     }
    //     return this._root;
    // }
}

export function creatElement(type, attributes, ...children) {
    // attributes {class: "app", id: "app"}
    let element;

    if(typeof type === 'string'){
        // 给所有的原生DOM对象加一个wrapper
        element = new ElementWrapper(type);
    } else {
        element = new type;
        console.log("typeof type !== 'string'",element);
    }

    for (let attributesKey in attributes) {
        if(attributes.hasOwnProperty(attributesKey)){
            element.setAttribute(attributesKey, attributes[attributesKey])
        }
    }
    let insertChildren = (children) => {
        for (let child of children) {
            let typeStr = typeof child;
            if(typeStr === "string"){
                child = new TextWrapper(child);
            }
            if(typeStr === 'object' && (child instanceof Array)){
                insertChildren(child)
            } else {
                element.appendChild(child)
            }
        }
    }
    insertChildren(children)
    return element;
}

export function render(component, parentElement) {
    let range = document.createRange();
    range.setStart(parentElement, 0)
    range.setEnd(parentElement, parentElement.childNodes.length)
    range.deleteContents();
    component[RENDER_TO_DOM](range);
}


